home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
425_01
/
tar
/
tape.c
< prev
next >
Wrap
Text File
|
1994-04-02
|
16KB
|
647 lines
/* tape.c - handle (tape) archive for the Tar program (see file tar.c)
* Author: T.V.Shaporev
* Creation date: 14 Dec 1990
* Contains both MS-DOS and UNIX specific codes
* Called by many functions - see files tar.c store.c extract.c
*/
#include <stdio.h>
#include <errno.h>
#include "sysup.h"
#include "modern.h"
#include "zippipe.h"
#include "lzwhead.h"
#include "compress.h"
#include "define.h"
#ifdef MODERN
# include <string.h>
# include <stdlib.h>
#else
# ifdef M_XENIX
# include <string.h>
# else
int strlen();
char *strcpy(), *strncpy(), *mktemp();
# endif
extern char *sys_errlist[];
extern int sys_nerr;
#endif
#ifdef MSDOS
# include <io.h>
# ifdef __TURBOC__
# include <dir.h>
# else
# include <direct.h>
# endif
#else
int creat(), open(), read(), write(), close();
long lseek();
#endif
static int n_read, mblock, nblock, rblock, wblock;
static int indread, indwrite;
static char rerror[] = "Tar: tape read error\n";
static int sread __ARGS__((char*, int));
static int swrite __ARGS__((char*, int));
static int sback __ARGS__((int));
#ifdef MSDOS
extern int dread __ARGS__((char*, int));
extern int dwrite __ARGS__((char*, int));
extern int dback __ARGS__((int));
extern int qparse __ARGS__((char*));
extern int qbegin __ARGS__((void));
extern int qread __ARGS__((char*, int));
extern int qwrite __ARGS__((char*, int));
extern int qback __ARGS__((int));
#endif
static void talign __ARGS__((long));
void printbs __ARGS__((int));
static void psyserr __ARGS__((void))
{
if (errno < sys_nerr) (void)fprintf(myout, "%s\n", sys_errlist[errno]);
else (void)fprintf(myout, "error %d\n", errno);
}
static int sread(buf, n) /* regular file reading */
char *buf; register n;
{
if ((n = read(handle, buf, n)) == -1) {
(void)fprintf(myout, "Tar: archive read error: "); psyserr();
}
return n;
}
static int swrite(buf, n) /* regular file writing */
char *buf; register n;
{
if (write(hwrite, buf, n) != n) {
(void)fprintf(myout, "Tar: archive write error: ");
#ifdef MSDOS
if (n != -1) (void)fprintf(myout,"disk full\n"); else
#endif
psyserr();
n = -1;
}
return n;
}
static int sback(n)
register n;
{
return lseek(handle, (long)-BLKSIZE*n, 1) < 0 ? -1 : n;
}
#ifdef USE_COMPRESS
static int zwrite __ARGS__((char*, int));
static int zwrite(buf, n) /* compressed file writing */
char *buf; register n;
{
cpiece(buf, n); return n;
}
#endif
static int gread __ARGS__((char*, int));
static int gwrite __ARGS__((char*, int));
static int gread(buf, n) /* deflated file reading */
char *buf; register n;
{
if ((n = unzread(buf, n)) == -1) {
(void)fprintf(myout, "Tar: unzip error: %s\n", ziperrlist[ziperror]);
}
return n;
}
static int gwrite(buf, n) /* deflated file reading */
char *buf; register n;
{
if ((n = zipwrite(buf, n)) == -1) {
(void)fprintf(myout, "Tar: unzip error: %s\n", ziperrlist[ziperror]);
}
return n;
}
static int ziperr __ARGS__((void))
{
(void)fprintf(stderr, "Tar: zip error: %s\n", ziperrlist[ziperror]);
return ziperror == ZNOMEM ? ESMALL : ERINIT;
}
#ifndef USE_COMPRESS
static int twofault __ARGS__((char*, int));
/*ARGSUSED2*/ static int twofault(buf, n)
char *buf; register n;
{
#ifdef __TURBOC__
(void)buf; (void)n;
#endif
return -1;
}
#endif
/*ARGSUSED*/ static int onefault(n)
int n;
{
#ifdef __TURBOC__
(void)n;
#endif
return -1;
}
static int (*pread) __ARGS__((char*, int)) = sread;
static int (*pwrite)__ARGS__((char*, int)) = swrite;
static int (*pback) __ARGS__((int)) = sback;
static int (*lread) __ARGS__((char*, int)) = sread;
static int (*lwrite)__ARGS__((char*, int)) = swrite;
static int (*lback) __ARGS__((int)) = sback;
static int (*rcount)__ARGS__((char*, int)) = sread;
static int cntread __ARGS__((char*, int));
int cntread(buf, n)
char *buf; register n;
{
if ((n = (*rcount)(buf, n)) != -1) {
allblock += (BLKSIZE-1 + (unsigned)n) / BLKSIZE;
}
return n;
}
static void talign(i)
long i;
{
if (i % BLKSIZE) {
(void)fprintf(myout, "Tar: tape blocksize error\n");
if (!i_flag) done(ERREAD);
}
}
void printbs(bs)
int bs;
{
if (v_flag) (void)fprintf(myout, "Tar: blocksize = %d\n", bs);
}
static void wrerror __ARGS__((void))
{
(void)fprintf(myout, "Tar: tape write error\n");
done(EWRITE);
}
static int indget;
static int eof_already = FALSE;
static int got_length;
static int indput;
static int getbyte __ARGS__(( void ))
{
if (eof_already) goto end;
if (indget >= got_length) {
if (pksize == 0) {
if ((got_length = (*lread)(pk_inp, MAXBLOCK*BLKSIZE)) < 0) goto err;
if ((sa.st_mode & S_IFMT) == S_IFCHR) talign((long)got_length);
pksize = got_length;
if ((pksize % BLKSIZE) == 0) printbs(pksize/BLKSIZE);
} else {
if (got_length < pksize || got_length % BLKSIZE) goto end;
if ((got_length = (*lread)(pk_inp, pksize)) < 0) goto err;
}
if (got_length < 1) goto end;
indget = 0;
}
return ((unsigned char *)pk_inp)[indget++];
err:
(void)fprintf(myout, rerror);
done(ERREAD);
end:
eof_already = TRUE;
return EOF;
}
static void pkflush __ARGS__((void))
{
#ifdef MSDOS
if (devtype != DEV_FILE && devtype != DEV_FLOP)
#else
if (!isfile)
#endif
while (indput < pksize) pk_out[indput++] = 0;
if ((*lwrite)(pk_out, indput) < indput) wrerror();
indput = 0;
}
static void putbyte(c)
register c;
{
if (indput >= pksize) {
#ifndef pksize
/* Buffer size must not be less then 512 bytes, so we */
/* can wait for blocksize will be detected by reading */
if (indput < BLKSIZE) goto put;
if (pksize < BLKSIZE) pksize = BLKSIZE;
#endif
pkflush();
}
put:
pk_out[indput++] = c;
}
int initape(name)
char *name;
{
#ifdef UNIX
char tn[10]; register char *n;
#endif
#ifdef MSDOS
register k;
#endif
handle = -1;
pread = lread = sread;
pwrite = lwrite = swrite;
pback = lback = sback;
if (name && name[0]=='-' && name[1]==0) {
if ((a_flag && !c_flag) || d_flag) {
(void)fprintf(stderr, "Tar: can\'t update stdout\n");
return ERRARG;
}
#ifdef myinp
if (j_flag
# ifndef MSDOS
|| w_flag
# endif
) {
(void)fprintf(stderr, "Tar: input must be free\n");
return ERRARG;
}
#endif
handle = a_flag ? /* stdout */ 1 : /* stdin */ 0;
myout = stderr;
} else {
#ifdef UNIX
if (name && name[0]) {
n = name;
} else {
n = strcpy(tn, "/dev/mt0"); tn[7] = (ndrive & 7) | '0';
}
handle = c_flag ? creat(n, 0666) :
open (n, a_flag && !d_flag ? O_RDWR : O_RDONLY);
if (handle < 0) {
cantopen(n); return ERINIT;
}
#endif
#ifdef MSDOS
if (!name || !name[0]) {
devtype = DEV_FLOP;
inidisk();
} else if ((k=qparse(name)) != FALSE) {
if (k != TRUE) return ERRARG;
pread = lread = qread;
pwrite = lwrite = qwrite;
pback = lback = qback;
devtype = DEV_QIC2;
} else {
if (!k_flag && defdev(name)==0) k_flag = TRUE;
if (k_flag) {
devtype = DEV_FLOP;
inidisk();
} else {
handle = open(name, !a_flag || d_flag ? O_RDONLY+O_BINARY :
c_flag ? O_CREAT+O_TRUNC+O_WRONLY+O_BINARY :
O_RDWR+O_BINARY,
S_IREAD+S_IWRITE);
if (handle < 0) {
cantopen(name); return ERINIT;
}
devtype = DEV_FILE;
}
}
if (devtype == DEV_FLOP) {
pread = lread = dread;
pwrite = lwrite = dwrite;
pback = lback = dback;
}
#endif
}